import json

from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import SKU
from meiduo_test.utils.cookiesecret import CookieSecret


class CartsView(View):

    def delete(self, request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        # 校验参数
        try:
            sku = SKU.objects.get(pk=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmag': '商品不存在'})
        # 手动判断是否登录
        user = request.user
        dumps_cookie_str = ''
        if user.is_authenticated:
            carts_redis_client = get_redis_connection('carts')
            carts_redis_client.hdel(user.id, sku_id)
        else:
            cookie_str = request.COOKIES.get('carts')
            if cookie_str:
                cart_dict = CookieSecret.loads(cookie_str)
            else:
                cart_dict = {}
            # 判断sku_id在不在购物车
            if sku_id in cart_dict:
                del cart_dict[sku_id]
                dumps_cookie_str = CookieSecret.dumps(cart_dict)

        #　统一返回响应对象
        response = JsonResponse({'code': '0', 'errmsg': 'OK'})
        # 6,二次判断是否登录　　没登录set_cookie
        if not user.is_authenticated:
            response.set_cookie('carts', dumps_cookie_str, max_age=14*24*3600)
        return response

    def put(self, request):
        # 1,接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        # 2,校验参数
        if not all([sku_id, count]):
            return JsonResponse({'code':400, 'errmsg':'参数不齐'})
        try:
            sku = SKU.objects.get(pk=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmag': '商品不存在'})
        try:
            count = int(count)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmag': 'count类型错误'})

        if not isinstance(selected, bool):
            return JsonResponse({'code': 400, 'errmag': 'selected类型错误'})

        # 3,手动判断是否登录
        user = request.user
        dumps_cookie_str = ''
        if user.is_authenticated:
            # 登录　
            # 获取redis链接对象
            carts_redis_client = get_redis_connection('carts')
            # 构建更新数据
            new_dict = {'count':count, 'selected':selected}
            # 直接覆盖
            carts_redis_client.hset(user.id, sku_id, json.dumps(new_dict))

        else:
            # 未登录
            # 从cookie中取出加密的购物车数据
            cookie_str = request.COOKIES.get('carts')
            # 如果有值解密
            if cookie_str:
                cart_dict = CookieSecret.loads(cookie_str)
            else:
                cart_dict = {}
            # 直接覆盖购物车数据
            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }
            # 加密修改完毕的数据
            dumps_cookie_str = CookieSecret.dumps(cart_dict)

        # ４，数据格式
        cart_sku = {
            'id': sku_id,
            'count': count,
            'selected': selected,

            'name': sku.name,
            'default_image_url': sku.default_image.url,
            'price': sku.price,
            'amount': sku.price * count,
        }

        # 5,返回响应对象
        response = JsonResponse({'code': '0', 'errmsg': 'OK', 'cart_sku': cart_sku})
        # 6,二次判断是否登录　　没登录set_cookie
        if not user.is_authenticated:
            response.set_cookie('carts', dumps_cookie_str, max_age=14*24*3600)
        return response

    def get(self, request):
        user = request.user
        if user.is_authenticated:
            # redis－－登录
            carts_redis_client = get_redis_connection('carts')

            carts_data = carts_redis_client.hgetall(user.id)
            carts_dict = {}
            for k, v in carts_data.items():
                sku_id = int(k.decode())
                sku_dict = json.loads(v.decode())
                # 构建一个新字典
                carts_dict[sku_id] = sku_dict
        else:
            # cookie－－未登录
            cookie_str = request.COOKIES.get('carts')
            if cookie_str:
                carts_dict = CookieSecret.loads(cookie_str)
            else:
                carts_dict = {}

        #　count  selected  sku_id   SKU查询sku
        sku_ids = carts_dict.keys()

        #　将数据转为json
        sku_list = []

        for sku_id in sku_ids:
            sku = SKU.objects.get(pk=sku_id)
            sku_list.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,

                'count': carts_dict.get(sku_id).get('count'),
                'selected': carts_dict.get(sku_id).get('selected'),
            })
        return JsonResponse({'code': 0, 'errmsg': 'OK', 'cart_skus': sku_list})

    def post(self, request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        # 校验参数　　判断count是否为int  selected是否是bool
        if not all([sku_id, count]):
            return JsonResponse({'code': 400, 'errmag':'参数不齐'})

        try:
            sku = SKU.objects.get(pk=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmag': '商品不存在'})

        try:
            count = int(count)
        except Exception as e:
            return JsonResponse({'code': 400, 'errmag': 'count类型错误'})

        if not isinstance(selected, bool):
            return JsonResponse({'code': 400, 'errmag': 'selected类型错误'})

        # 手动判断是否登录
        if request.user.is_authenticated:
            # 登录－－redis
            # 1. 链接 redis 对象
            carts_redis_client = get_redis_connection('carts')

            # 2. 获取当前用户 的所有购物车数据 -- bytes    {b'1':b'{count:2,selected:true}'}
            client_data = carts_redis_client.hgetall(request.user.id)

            # 3. 判断 当前商品以前有没有添加过-- hset()
            if str(sku_id).encode() in client_data:
                # 3.1 根据 sku_id 取对应商品的购物车数据 b'{count:2,selected:true}' == client_data[str(sku_id).encode() ]
                child_dict = json.loads((client_data[str(sku_id).encode()]).decode())

                # 3.2 取出老的 购买个数 + 新的购买个数
                count = child_dict['count'] + count

                # 3.3 更新数据
                carts_redis_client.hset(request.user.id, sku_id, json.dumps({'count': count, 'selected': selected}))
            else:
                #   直接新增 hset()
                carts_redis_client.hset(request.user.id, sku_id, json.dumps({'count': count, 'selected': selected}))

            # 4.返回响应对象
            return JsonResponse({'code': 0, 'errmsg': 'Ok!'})

        else:
            # 未登录－－cookie
            # 1. 取出Cookie的购物车数据  request.COOKIES.get('carts')
            carts_str = request.COOKIES.get('carts')
            # 2. 解密--cart_dict = {有值}
            # 3.创建一个空字典 cart_dict = { }
            if carts_str:
                carts_dict = CookieSecret.loads(carts_str)
            else:
                carts_dict = {}

            # 4.如果这个商品 存在 以前的 cookie数据中
            if sku_id in carts_dict:
                #    取出老的商品 个数 + count 新的个数  累加
                origin_count = carts_dict[sku_id]['count']
                count = origin_count + count

            # 5.无论是新sku 还是 老sku --直接都覆盖
            carts_dict[sku_id] = {
                'count':count,
                'selected':selected
            }
            # 6.加密--str
            cookie_cart_str = CookieSecret.dumps(carts_dict)
            # 7.设置cookie
            response = JsonResponse({'code': 0, 'errmag': 'OK'})
            response.set_cookie('carts', cookie_cart_str, max_age=14 * 24 * 3600)
            # 8.返回 json
            return response
